<template>
  <div class="p-2">
    <el-card shadow="never">
      <template #header>
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:datasetPrediction:add']">新增</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:datasetPrediction:edit']"
              >修改</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:datasetPrediction:remove']"
              >删除</el-button
            >
          </el-col>
          <el-col :span="1.5">
            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:datasetPrediction:export']">导出</el-button>
          </el-col>
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>
      </template>

      <el-table v-loading="loading" :data="datasetPredictionList" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="模拟器（功率）" align="center" prop="simulatorPower" />
        <el-table-column label="回路（测点数）" align="center" prop="circuitMeasurement" />
        <el-table-column label="特征选择数" align="center" prop="impMeasurement" />
        <el-table-column label="数据类型" align="center" prop="datasetType">
          <template v-slot="scope">
            {{ lsc_data_type.find(item => item.value === scope.row.datasetType)?.label || '未知类型' }}
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center" prop="state">
          <template v-slot="scope">
            <div v-if="scope.row.state == '1'" style="color:#1ab394;">
              {{ getState(scope.row) }}
            </div>
            <div v-else style="color: red;">
              {{ getState(scope.row) }}
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="300">
          <template #default="scope">
            <el-tooltip content="修改" placement="top">
              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:datasetPrediction:edit']"
                >修改</el-button
              >
            </el-tooltip>
            <el-tooltip content="训练" placement="top">
              <el-button link type="primary" icon="Aim" @click="handlePrediction(scope.row)" v-hasPermi="['system:datasetPrediction:edit']"
                >{{getWord(scope.row.datasetType)}}</el-button
              >
            </el-tooltip>
            <el-tooltip content="删除" placement="top">
              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:datasetPrediction:remove']"
                >删除</el-button
              >
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
    </el-card>
    <!-- 添加或修改【请填写功能名称】对话框 -->
    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
      <el-form ref="datasetPredictionFormRef" :model="form" :rules="rules" label-width="120px">
        <el-form-item label="模拟器(功率):" prop="simulatorPower">
          <el-input v-model="form.simulatorPower" placeholder="请输入模拟器(功率)" />
        </el-form-item>
        <el-form-item label="回路(测点数):" prop="circuitMeasurement">
          <el-input v-model="form.circuitMeasurement" placeholder="请输入回路(测点数)" />
        </el-form-item>
        <el-form-item label="特征选择数:" prop="impMeasurement">
          <el-input v-model="form.impMeasurement" placeholder="请输入重要测点数量，特征选择" />
        </el-form-item>
        <el-form-item label="数据选择:" prop="dataId">
          <el-select v-model="form.dataId" placeholder="请选择数据类型" clearable>
            <el-option v-for="dict in dataDict.value" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="数据类型:" prop="datasetType">
          <el-select v-model="form.datasetType" placeholder="请选择数据类型" clearable>
            <el-option v-for="dict in lsc_data_type" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog :title="dialogS.title" v-model="dialogS.visible" width="500px" append-to-body>
      <cnn :data-id="dataId" :pred-id="predId" />
    </el-dialog>
    <el-dialog :title="dialogT.title" v-model="dialogT.visible" width="500px" append-to-body>
      <div v-if="showTable">
        <line-charts min="40" width="450px" height="300px" title="预测结果展示" :legend="legend" :series="series[0]" :x-axis="xAxis" />
        <div style="width: 100%;text-align: center">
          <span>平均值：{{average}};</span>
          <span style="margin-left: 10px">标准差：{{standard}}</span>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup name="DatasetPrediction" lang="ts">
import { listDatasetPrediction, getDatasetPrediction, delDatasetPrediction, addDatasetPrediction, updateDatasetPrediction } from '@/api/wyl/prediction';
import { DatasetPredictionVO, DatasetPredictionQuery, DatasetPredictionForm } from '@/api/wyl/prediction/types';
import router from "@/router";
import { listDetail } from "@/api/wyl/detail";
import axios from "_axios@1.6.2@axios";
import { globalHeaders } from "@/utils/request";
import { blobValidate } from "@/utils/ruoyi";
import * as XLSX from "_xlsx@0.18.5@xlsx";

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const dataId = ref('')
const datasetPredictionList = ref<DatasetPredictionVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const showTable = ref(false);
const total = ref(0);
const legend = ref([] as any[])
const series = ref([] as any[])
const xAxis = ref([] as any[])
interface DataDict {
  value: { label: string; value: string | number }[];
}

const dataDict = reactive<DataDict>({
  value: []
});
const queryFormRef = ref<ElFormInstance>();
const datasetPredictionFormRef = ref<ElFormInstance>();
const {lsc_data_type} = toRefs<any>(proxy?.useDict('lsc_data_type'));
const dialog = reactive<DialogOption>({
  visible: false,
  title: ''
});
const dialogS = reactive<DialogOption>({
  visible: false,
  title: ''
});
const dialogT = reactive<DialogOption>({
  visible: false,
  title: ''
});
const initFormData: DatasetPredictionForm = {
  id: undefined,
  simulatorPower: undefined,
  circuitMeasurement: undefined,
  impMeasurement: undefined,
  datasetType: undefined,
  state: undefined,
}
const data = reactive<PageData<DatasetPredictionForm, DatasetPredictionQuery>>({
  form: {...initFormData},
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    simulatorPower: undefined,
    circuitMeasurement: undefined,
    impMeasurement: undefined,
    datasetType: undefined,
    state: undefined,
    params: {
    }
  },
  rules: {
    id: [
      { required: true, message: "不能为空", trigger: "blur" }
    ],
    dataId: [
      { required: true, message: "数据集不能为空", trigger: "blur" }
    ],
    simulatorPower: [
      { required: true, message: "模拟器不能为空", trigger: "blur" }
    ],
    circuitMeasurement: [
      { required: true, message: "回路不能为空", trigger: "blur" }
    ],
    impMeasurement: [
      { required: true, message: "重要测点数量，特征选择不能为空", trigger: "blur" }
    ],
    datasetType: [
      { required: true, message: "数据类型不能为空", trigger: "change" }
    ],
    state: [
      { required: true, message: "状态不能为空", trigger: "blur" }
    ],
  }
});

const { queryParams, form, rules } = toRefs(data);
onMounted(() => {
  init()
})
const init = async () => {
  const res = await listDetail();
  console.log(res.rows);
  res.rows.forEach(row => {
    dataDict.value.push({
      value: row.dataFile,
      label: row.healthState
    })
  })
}
/** 查询【请填写功能名称】列表 */
const getList = async () => {
  loading.value = true;
  const res = await listDatasetPrediction(queryParams.value);
  datasetPredictionList.value = res.rows;
  total.value = res.total;
  loading.value = false;
}

/** 取消按钮 */
const cancel = () => {
  reset();
  dialog.visible = false;
}

/** 表单重置 */
const reset = () => {
  form.value = {...initFormData};
  datasetPredictionFormRef.value?.resetFields();
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
}

/** 多选框选中数据 */
const handleSelectionChange = (selection: DatasetPredictionVO[]) => {
  ids.value = selection.map(item => item.id);
  single.value = selection.length != 1;
  multiple.value = !selection.length;
}

/** 新增按钮操作 */
const handleAdd = () => {
  reset();
  dialog.visible = true;
  dialog.title = "添加预测";
}

/** 修改按钮操作 */
const handleUpdate = async (row?: DatasetPredictionVO) => {
  reset();
  const _id = row?.id || ids.value[0]
  const res = await getDatasetPrediction(_id);
  Object.assign(form.value, res.data);
  dialog.visible = true;
  dialog.title = "修改预测";
}
const getState = (row?: DatasetPredictionVO) => {
  const state = row?.state;
  const dataType = row?.datasetType
  if (dataType == "0") {
    return state == "0" ? "未训练" : "已训练";
  } else {
    return "";
  }
}
const predId = ref("")
const handlePrediction = (row?: DatasetPredictionVO) => {
  dataId.value = String(row?.dataId);
  predId.value = String(row?.id);
  if (row?.datasetType == '0') {
    dialogS.visible = true
  } else {
    dialogT.visible = true
    getData(dataId.value)
  }
}
/** 提交按钮 */
const submitForm = () => {
  form.value.state = "0";
  datasetPredictionFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      buttonLoading.value = true;
      if (form.value.id) {
        await updateDatasetPrediction(form.value).finally(() =>  buttonLoading.value = false);
      } else {
        await addDatasetPrediction(form.value).finally(() =>  buttonLoading.value = false);
      }
      proxy?.$modal.msgSuccess("修改成功");
      dialog.visible = false;
      await getList();
    }
  });
}
const getWord = (dataType?: string) => {
  return dataType == "0" ? "预测训练" : "预测测试";
}
/** 删除按钮操作 */
const handleDelete = async (row?: DatasetPredictionVO) => {
  const _ids = row?.id || ids.value;
  await proxy?.$modal.confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项？').finally(() => loading.value = false);
  await delDatasetPrediction(_ids);
  proxy?.$modal.msgSuccess("删除成功");
  await getList();
}

/** 导出按钮操作 */
const handleExport = () => {
  proxy?.download('system/datasetPrediction/export', {
    ...queryParams.value
  }, `datasetPrediction_${new Date().getTime()}.xlsx`)
}

onMounted(() => {
  getList();
});
const baseURL = import.meta.env.VITE_APP_BASE_API;
const getData = async (ossId: string) => {
  const url = baseURL + '/resource/oss/download/' + ossId;
  const res = await axios({
    method: 'get',
    url: url,
    responseType: 'blob',
    headers: globalHeaders()
  });
  const isBlob = blobValidate(res.data);
  if (isBlob) {
    const blob = new Blob([res.data], { type: 'application/octet-stream' });
    console.log('blob', blob)
    await readExcel(blob)
  }
}
const average = ref("");
const standard = ref("")
const readExcel = async (file: Blob) => {
  // 确保有文件可读
  if (!file) {
    alert('请先选择一个Excel文件');
    return;
  }
  series.value = [];
  const reader = new FileReader();
  // 读取文件完成后的回调
  reader.onload = (event) => {
    const data = new Uint8Array((event.target as any).result);
    // 使用 xlsx 读取数据
    const workbook = XLSX.read(data, { type: 'array' });
    // 获取第一个工作表
    const firstSheetName = workbook.SheetNames[0];
    const worksheet = workbook.Sheets[firstSheetName];
    console.log("data", worksheet)
    const jsonData = ref([] as any[])
    // 将 Excel 数据转换为 JSON 对象
    jsonData.value = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
    console.log("reader", jsonData.value)
    if (jsonData.value.length > 0) {
      jsonData.value[0].forEach((item: any) => {
        legend.value.push(item);
      });
    }
    xAxis.value = Array.from({ length: jsonData.value.length - 1 }, (_, i) => String(i + 1));
    const colData = []
    for (let i = 1; i < jsonData.value.length; i++) {
      colData.push(jsonData.value[i][0])
    }
    console.log("colData", colData);
    // 创建一个新的数据对象
    const newData = {
      name: legend.value[0],  // 使用 legend 中的数据作为 name 属性
      type: 'bar',             // 设置 type 属性为 'line'
      smooth: true,
      data: colData             // 将列数据推导到 data 属性里
    };
    // 将数据对象添加到 dataDict 数组
    series.value.push(newData);
    showTable.value = true;
    // 计算平均值
    const averages = (colData.reduce((sum, value) => sum + value, 0) / colData.length).toFixed(3);
    // 计算方差
    const variance = colData.reduce((sum, value) => sum + Math.pow(value - Number(averages), 2), 0) / colData.length;
    // 计算标准差
    const standards = Math.sqrt(variance).toFixed(3);
    average.value = parseFloat(averages).toFixed(3);
    standard.value = parseFloat(standards).toFixed(3);
    console.log("legend:", legend.value);
    console.log("series:", series.value);
  };
  // 读取文件为 ArrayBuffer
  reader.readAsArrayBuffer(file);
};
</script>
